const shortid = require('shortid');
const bcrypt = require('bcrypt');
const _ = require('lodash');

/**
 * 个人账号相关功能
 * @param app
 */
const prefix = '/api/account';
const resetPasswordKey = 'reset-password:';
const sendCodeKey = 'send-code:';
module.exports = (app) => {
    const {router, middleware} = app;

    /**获取Geetest数据*/
    router.get(prefix + '/get-geetest-data', async ctx => {
        ctx.body = await ctx.service.geetest.getGeetestData();
    });

    /**发送验证码*/
    router.post(prefix + '/send-code', async ctx => {
        const data = ctx.request.body;
        const email = data.input;
        const sendKey = sendCodeKey + email;

        const check = await ctx.app.redis.ttl(sendKey);

        if (check > 0)
            return ctx.helper.error(`请等待 ${check} 秒后再申请发送验证码`);

        const {error, success} = await ctx.service.geetest.checkGeetestData(data.geetest);
        if (error)
            return ctx.helper.error(error.message);
        if (!success)
            return ctx.helper.error('验证码校验失败，请稍后再试');
        const user = await ctx.app.model.User.findOne({where: {email: data.input}});
        if (!user)
            return ctx.helper.error(`没有与 ${data.input} 相关的用户`);
        /**输入的是邮箱，需要发送邮件*/
        const code = shortid.generate();
        ctx.service.mail.send({to: user.email, subject: '申请重置密码的验证码', html: `<h2>重置密码的验证码：${code}</h2>`});
        await ctx.app.redis.set(sendKey, '', 'ex', 60);
        await ctx.app.redis.set(resetPasswordKey + code, user.id, 'ex', 600);
        ctx.body = 'ok';
    });

    /**重设密码*/
    router.post(prefix + '/reset-password', async ctx => {
        let {password, code} = ctx.request.body;
        if (_.isEmpty(password) || password.length < 6)
            return ctx.helper.error('密码长度需要6位字符以上');
        else if (_.isEmpty(code))
            return ctx.helper.error('请填写重置密码的验证码');
        const key = resetPasswordKey + code;
        if (0 > await ctx.app.redis.ttl(key))
            return ctx.helper.error('验证码无效，可能已经过期');

        password = await bcrypt.hash(password, 4);

        const id = await ctx.app.redis.get(resetPasswordKey + code);
        const user = await ctx.app.model.User.findByPk(id);
        await user.update({password});
        ctx.body = 'ok';
        ctx.app.redis.del(key);
    });


    /**我的账号资料*/
    router.get(prefix + '/edit', middleware.api(), async ctx => {
        ctx.body = await ctx.app.model.User.findOne({
            where: {id: ctx.user.id},
            include: [
                {model: ctx.app.model.UserLevel, as: 'level'},
            ],
        });
    });

    /**修改 我的账号资料*/
    router.post(prefix + '/edit', middleware.api(), async ctx => {
        const user = await ctx.app.model.User.findByPk(ctx.user.id);
        const data = ctx.request.body;
        if (_.isEmpty(data.phone))
            return ctx.helper.error('需要填写手机号码');
        if (_.isEmpty(data.email))
            return ctx.helper.error('需要填写邮箱地址');
        if (data.phone !== user.phone) {
            if (0 !== await ctx.app.model.User.count({
                    where: {
                        id: {[ctx.app.Sequelize.Op.not]: user.id},
                        phone: data.phone
                    }
                }))
                return ctx.helper.error(data.phone + ' 已经被他人使用');
        }
        if (data.email !== user.email) {
            if (0 !== await ctx.app.model.User.count({
                    where: {
                        id: {[ctx.app.Sequelize.Op.not]: user.id},
                        email: data.email,
                    }
                }))
                return ctx.helper.error(data.email + ' 已经被他人使用');
        }

        const updateData = {phone: data.phone, email: data.email};

        if (data.modifyPassword) {
            if (!await bcrypt.compare(data.password, user.password))
                return ctx.helper.error('与原有的密码匹配失败，无法修改密码。可以退出登录使用重置密码功能。');

            if (data.newPassword && data.newPassword.length >= 6) {
                updateData.password = await bcrypt.hash(data.newPassword, 4);
            } else {
                return ctx.helper.error('密码需要6位以上字符');
            }
        }

        await user.update(updateData);
        ctx.body = 'ok';
    });
};